package lovedna.display.movieclip {
	import flash.utils.getTimer;

	/**
	 * @author hi
	 */
	public class MovieClipFrameList {
		protected var _name : String = "";
		protected var _list : Array = [];
		protected var _length : int;
		protected var _timeline : Array = [];
		protected var _totalTime : Number = 0;
		protected var _timeInc : Number = 0;
		protected var _timeScale : Number = 1;
		protected var _percent : Number = 0;

		public function MovieClipFrameList(name : String = "") {
			_name = name;
		}

		public function reverse() : void {
			_list = _list.reverse();
			update();
		}

		public function set timeScale(value : Number) : void {
			_timeScale = value;
			update();
		}

		public function addFrame(value : MovieClipFrame, index : int = -1) : void {
			if (index < 0) {
				index = _length;
			}
			if (index < _length) {
				_list.splice(index, 0, value);
			} else {
				_list[index] = value;
			}
			update();
		}

		public function updateFrame(value : MovieClipFrame, index : int) : void {
			_list[index] = value;
			update();
		}

		public function removeFrame(index : int) : void {
			if (index < _length) {
				_list.splice(index, 1);
				update();
			}
		}

		public function getFrame(index : int) : MovieClipFrame {
			var frame : MovieClipFrame;
			if (index < _length) {
				frame = _list[index];
				if (frame == null) {
					frame = new MovieClipFrame();
					_list[index] = frame;
				}
			}
			return frame;
		}

		public function getFrameTime(index : int) : Number {
			var frame : MovieClipFrame = getFrame(index);
			return frame.delay * _timeScale;
		}

		public function gotoFrame(index : int) : void {
			index--;
			if (index < 0) index = 0;
			if (index > _length) index = _length;
			var t : Number = _timeline[index];
			percent = t / _totalTime;
		}

		public function getTimeIndex(time : Number) : int {
			time -= _timeInc;
			time %= _totalTime;
			if (time < 0) time = _totalTime - time;
			_percent = time / _totalTime;
			var half : int = _length * 0.5;
			var left : int = 0;
			var right : int = _length - 1;
			var m : int = _timeline[half];
			if (time < m) {
				right = half;
			} else {
				left = half;
			}
			while (true) {
				var inc : int = right - left;
				if (inc != 0) {
					half = inc * 0.5;
					m = _timeline[left + half];
					if (time < m) {
						right = left + half;
					} else {
						left = right - half;
					}
				} else {
					return right < 0 ? 0 : right;
				}
			}
			return 0;
		}

		public function concat(value : MovieClipFrameList) : void {
			_list = _list.concat(value._list);
			update();
		}

		private function update() : void {
			_length = _list.length;
			_totalTime = 0;
			_timeline = [];
			for (var i : int = 0;i < _length;i++) {
				var frame : MovieClipFrame = _list[i];
				if (frame) {
					_totalTime += frame.delay * _timeScale;
					_timeline.push(_totalTime);
				} else {
					_timeline.push(_totalTime);
				}
			}
			if (_totalTime == 0) {
				_totalTime = 1;
			}
		}

		public function get name() : String {
			return _name;
		}

		public function get length() : int {
			return _length;
		}

		public function get percent() : Number {
			return _percent;
		}

		public function set percent(value : Number) : void {
			_timeInc = (getTimer() - value * _totalTime) % _totalTime;
		}

		public function get totalTime() : Number {
			return _totalTime;
		}

		public function clone() : MovieClipFrameList {
			var clone : MovieClipFrameList = new MovieClipFrameList();
			clone._name = _name;
			clone._length = _length;
			clone._list = _list.concat();
			clone._timeInc = _timeInc;
			clone._percent = _percent;
			clone._timeline = _timeline.concat();
			clone._timeScale = _timeScale;
			clone._totalTime = _totalTime;
			return clone;
		}

		public function copy(indexlist : Array) : MovieClipFrameList {
			if (indexlist == null) {
				return clone();
			}
			var len : int = indexlist.length;
			if (len == 0) {
				return clone();
			}
			var copy : MovieClipFrameList = new MovieClipFrameList();
			for (var i : int = 0;i < len;i++) {
				var index : int = indexlist[i];
				if (index < _length) {
					copy._list.push(_list[index]);
				}
			}
			copy.update();
			return copy;
		}
	}
}
